#ifndef IPSOCKET_H
#define IPSOCKET_H

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

//注意服务器要先建立，然后客户端要先发送（！！！）。
class ipsocket{
public:
	ipsocket():socket_type(0),socket_fd(0),SocketAddrlength(0),isValic(false){
		memset(&SocketAddr,0,sizeof(SocketAddr));
	}
	~ipsocket(){};
	int getSocketFD(){return socket_fd;}
	bool creatServer(string name, const int port){
		if(socket_fd!=0)return false;
		__socket_type type = SOCK_DGRAM;
		if(name=="TCP"){
			type = SOCK_STREAM;
			socket_type = 1;
		}
		if((socket_fd = socket(AF_INET,type,0)) == -1){
	    	perror("socket created error");
	    	return false;
	    }
		memset(&SocketAddr,0,sizeof(SocketAddr));
		SocketAddr.sin_family = AF_INET,
		SocketAddr.sin_addr.s_addr = htonl(INADDR_ANY);
		SocketAddr.sin_port = htons(port);
		SocketAddrlength = sizeof(SocketAddr);
		if(bind(socket_fd,(struct sockaddr *)&SocketAddr,SocketAddrlength)!=0){
			perror("socket bind error!\n");
			return false;
		}
        if(socket_type){
        	if(listen(socket_fd, 10) != 0){
		        perror("socket listen error");
		        return false;
        	}
        	moni_fd = socket_fd;
        	if((socket_fd = accept(moni_fd, NULL, 0)) < 0 ){
		        perror("accept error!\n");
		        return false;
		    }
        }
        isValic = true;
        return true;
	}
	bool creatClient(string name, string IPAddr, const int port){
		if(socket_fd!=0)return false;
		__socket_type type = SOCK_DGRAM;
		if(name=="TCP"){
			type = SOCK_STREAM;
			socket_type = 1;
		}
		if((socket_fd = socket(AF_INET,type,0)) == -1){
			perror("socket created error");
			return false;
		}
		memset(&SocketAddr,0,sizeof(SocketAddr));
		SocketAddr.sin_family = AF_INET;
		SocketAddr.sin_addr.s_addr = inet_addr(IPAddr.c_str());
		SocketAddr.sin_port = htons(port);
		SocketAddrlength = sizeof(SocketAddr);
		if(socket_type){
			if(connect(socket_fd,(struct sockaddr *)&SocketAddr,SocketAddrlength)!=0){
		   		perror("connect failed\n");
		   		return false;
	   		}
	  	}
	  	isValic = true;
        return true;
	}
	void RecvPackets(char* buf,int& buf_len ){
		int ret = 0;
		if(socket_type)
			ret=recv(socket_fd, buf, buf_len, 0);
		else
			ret=recvfrom(socket_fd,buf,buf_len,0,(struct sockaddr *)&SocketAddr,&SocketAddrlength);
        if(ret<0)
        	perror("data receive error");
	} 
	void SendPackets(char* buf,int buf_len ){
		int ret=0;
		if(socket_type)
			ret=send(socket_fd, buf, buf_len, 0 );
		else 
			ret=sendto(socket_fd,buf,buf_len,0,(struct sockaddr *)&SocketAddr,SocketAddrlength);
		if(ret<0)
        	perror("data send error");
	}
private:
	int socket_type;  //0:UDP 1:TCP
	bool isValic;
	int socket_fd,moni_fd;
    struct sockaddr_in SocketAddr;
    socklen_t SocketAddrlength;
};

#endif

